import argparse
import json
import os
from analyzer.addr2line_analyzer import Addr2LineAnalyzer
from analyzer.perf_dump_analyzer import PerfDumpAnalyzer
from analyzer.sourceline_analyzer import SourcelineAnalyzer
from html_report_generator import HtmlReportGenerator


def load_config(config_file):
    with open(config_file, 'r') as f:
        return json.load(f)


def main(perf_dump_file, llvm_bin_path, so_files_path):
    current_dir = os.path.dirname(os.path.abspath(__file__))

    perf_dump_file = os.path.join(current_dir, perf_dump_file)
    llvm_bin_path = os.path.join(current_dir, llvm_bin_path)
    so_files_path = os.path.join(current_dir, so_files_path)

    perf_analyzer = PerfDumpAnalyzer(perf_dump_file)
    addr2line_analyzer = Addr2LineAnalyzer(perf_analyzer, llvm_bin_path, so_files_path)
    sourceline_analyzer = SourcelineAnalyzer(llvm_bin_path, so_files_path)

    addr2line_result = addr2line_analyzer.analyze_addresses()

    hot_files = addr2line_analyzer.aggregate_by_file(addr2line_result)
    hot_lines = addr2line_analyzer.aggregate_by_line(addr2line_result)

    assembly_info = sourceline_analyzer.analyze(addr2line_result)

    report_generator = HtmlReportGenerator()
    report_generator.generate_report(hot_files, hot_lines, assembly_info)

    print(f"Total period: {perf_analyzer.get_total_period()}")


if __name__ == "__main__":
    config = load_config('config.json')

    parser = argparse.ArgumentParser(description="Analyze performance dump and resolve addresses.")
    parser.add_argument("--perf_dump_file", default='data/perf.dump',
                        help="Path to the performance dump file")
    parser.add_argument("--so_files_path", default='data/so_files',
                        help="Path to the directory containing .so files")
    parser.add_argument("--llvm_bin_path", default=config["llvm_bin_path"],
                        help="Path to the llvm-symbolize executable")

    args = parser.parse_args()
    main(args.perf_dump_file, args.llvm_bin_path, args.so_files_path)
